/**
 * WebSocket客户端管理器
 * 用于替代轮询机制，实现实时消息推送
 */
class WebSocketClient {
  constructor() {
    this.ws = null
    this.userId = null
    this.isConnected = false
    this.reconnectTimer = null
    this.heartbeatTimer = null
    this.reconnectAttempts = 0
    this.maxReconnectAttempts = 5
    this.reconnectInterval = 5000 // 5秒重连间隔
    this.heartbeatInterval = 30000 // 30秒心跳间隔
    
    // 事件监听器
    this.listeners = {
      onMessage: [],
      onConnect: [],
      onDisconnect: [],
      onError: []
    }
  }
  
  /**
   * 检查WebSocket服务器是否可用
   * @returns {Promise<boolean>} 服务器是否可用
   */
  async checkServerAvailability() {
    try {
      const protocol = window.location.protocol
      const host = window.location.hostname
      const port = '8086'
      const healthCheckUrl = `${protocol}//${host}:${port}/api/health`
      
      const response = await fetch(healthCheckUrl, {
        method: 'GET',
        timeout: 5000,
        headers: {
          'Accept': 'application/json'
        }
      })
      
      if (response.ok) {
        console.log('WebSocket服务器健康检查通过')
        return true
      } else {
        console.warn('WebSocket服务器健康检查失败:', response.status)
        return false
      }
    } catch (error) {
      console.warn('WebSocket服务器健康检查异常:', error.message)
      return false
    }
  }

  /**
   * 连接WebSocket服务器
   * @param {string} userId 用户ID
   */
  async connect(userId) {
    if (!userId) {
      console.error('WebSocket连接失败：用户ID不能为空')
      return
    }
    
    this.userId = userId
    
    // 如果已经连接，先断开
    if (this.ws && (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING)) {
      this.disconnect()
    }
    
    // 在连接前检查服务器可用性（仅在首次连接时检查，避免重连时的延迟）
    if (this.reconnectAttempts === 0) {
      const serverAvailable = await this.checkServerAvailability()
      if (!serverAvailable) {
        console.warn('WebSocket服务器不可用，将使用轮询模式')
        this.emit('onError', new Error('WebSocket服务器不可用'))
        return
      }
    }
    
    try {
      // 构造WebSocket连接URL
      const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'
      const host = window.location.hostname
      const port = '8086' // WebSocket推送服务端口
      const wsUrl = `${protocol}//${host}:${port}/websocket/message/${userId}`
      
      console.log('正在连接WebSocket服务器:', wsUrl)
      
      this.ws = new WebSocket(wsUrl)
      
      // 设置连接超时
      const connectionTimeout = setTimeout(() => {
        if (this.ws && this.ws.readyState === WebSocket.CONNECTING) {
          console.warn('WebSocket连接超时，关闭连接')
          this.ws.close()
        }
      }, 10000) // 10秒超时
      
      // 连接成功时清除超时定时器
      this.ws.addEventListener('open', () => {
        clearTimeout(connectionTimeout)
      }, { once: true })
      
      this.setupEventHandlers()
      
    } catch (error) {
      console.error('WebSocket连接异常:', error)
      this.handleError(error)
    }
  }
  
  /**
   * 设置WebSocket事件处理器
   */
  setupEventHandlers() {
    this.ws.onopen = (event) => {
      console.log('WebSocket连接成功')
      this.isConnected = true
      this.reconnectAttempts = 0
      
      // 启动心跳检测
      this.startHeartbeat()
      
      // 触发连接成功事件
      this.emit('onConnect', event)
    }
    
    this.ws.onmessage = (event) => {
      try {
        const data = JSON.parse(event.data)
        console.log('收到WebSocket消息:', data)
        
        // 处理不同类型的消息
        switch (data.type) {
          case 'connection':
            console.log('连接确认:', data.message)
            break
          case 'heartbeat':
            console.log('心跳响应')
            break
          case 'newMessage':
            this.handleNewMessage(data)
            break
          case 'messageUpdate':
            this.handleMessageUpdate(data)
            break
          case 'markReadResponse':
            console.log('标记已读响应:', data)
            break
          default:
            console.log('未知消息类型:', data.type)
        }
        
        // 触发消息事件
        this.emit('onMessage', data)
        
      } catch (error) {
        console.error('解析WebSocket消息失败:', error)
      }
    }
    
    this.ws.onclose = (event) => {
      console.log('WebSocket连接关闭:', event.code, event.reason)
      this.isConnected = false
      this.stopHeartbeat()
      
      // 详细的关闭代码说明
      const closeReasons = {
        1000: '正常关闭',
        1001: '端点离开',
        1002: '协议错误',
        1003: '不支持的数据类型',
        1005: '未收到状态码',
        1006: '连接异常关闭',
        1007: '数据格式错误',
        1008: '策略违规',
        1009: '消息过大',
        1010: '扩展协商失败',
        1011: '服务器错误',
        1015: 'TLS握手失败'
      }
      
      const reason = closeReasons[event.code] || '未知错误'
      console.log(`WebSocket关闭详情: ${event.code} - ${reason}`)
      
      // 触发断开连接事件
      this.emit('onDisconnect', { ...event, reasonText: reason })
      
      // 尝试重连（非主动关闭的情况下）
      if (event.code !== 1000 && this.reconnectAttempts < this.maxReconnectAttempts) {
        console.log(`准备重连，当前尝试次数: ${this.reconnectAttempts}/${this.maxReconnectAttempts}`)
        this.scheduleReconnect()
      } else if (this.reconnectAttempts >= this.maxReconnectAttempts) {
        console.error('已达到最大重连次数，停止重连')
        this.emit('onError', new Error('WebSocket重连失败，已达到最大重连次数'))
      }
    }
    
    this.ws.onerror = (error) => {
      console.error('WebSocket连接错误:', error)
      this.handleError(error)
    }
  }
  
  /**
   * 处理新消息
   */
  handleNewMessage(data) {
    console.log('收到新消息:', data.data)
    
    // 触发自定义事件，通知消息通知组件
    const messageEvent = new CustomEvent('newWebSocketMessage', {
      detail: data.data
    })
    window.dispatchEvent(messageEvent)
  }
  
  /**
   * 处理消息更新
   */
  handleMessageUpdate(data) {
    console.log('消息状态更新:', data.data)
    
    // 触发自定义事件
    const updateEvent = new CustomEvent('messageStatusUpdate', {
      detail: data.data
    })
    window.dispatchEvent(updateEvent)
  }
  
  /**
   * 发送消息到服务器
   */
  send(data) {
    if (this.isConnected && this.ws.readyState === WebSocket.OPEN) {
      this.ws.send(JSON.stringify(data))
      return true
    } else {
      console.warn('WebSocket未连接，消息发送失败')
      return false
    }
  }
  
  /**
   * 发送心跳消息
   */
  sendHeartbeat() {
    this.send({
      type: 'heartbeat',
      timestamp: Date.now()
    })
  }
  
  /**
   * 标记消息为已读
   */
  markMessageAsRead(messageId) {
    return this.send({
      type: 'markRead',
      messageId: messageId,
      timestamp: Date.now()
    })
  }
  
  /**
   * 启动心跳检测
   */
  startHeartbeat() {
    this.stopHeartbeat() // 先清除之前的定时器
    this.heartbeatTimer = setInterval(() => {
      this.sendHeartbeat()
    }, this.heartbeatInterval)
  }
  
  /**
   * 停止心跳检测
   */
  stopHeartbeat() {
    if (this.heartbeatTimer) {
      clearInterval(this.heartbeatTimer)
      this.heartbeatTimer = null
    }
  }
  
  /**
   * 安排重连
   */
  scheduleReconnect() {
    if (this.reconnectTimer) {
      clearTimeout(this.reconnectTimer)
    }
    
    this.reconnectAttempts++
    const delay = this.reconnectInterval * Math.pow(2, Math.min(this.reconnectAttempts - 1, 3)) // 指数退避
    
    console.log(`将在${delay}ms后进行第${this.reconnectAttempts}次重连`)
    
    this.reconnectTimer = setTimeout(() => {
      if (this.userId) {
        this.connect(this.userId)
      }
    }, delay)
  }
  
  /**
   * 断开连接
   */
  disconnect() {
    this.stopHeartbeat()
    
    if (this.reconnectTimer) {
      clearTimeout(this.reconnectTimer)
      this.reconnectTimer = null
    }
    
    if (this.ws) {
      this.ws.close(1000, '主动断开连接')
      this.ws = null
    }
    
    this.isConnected = false
    this.reconnectAttempts = 0
  }
  
  /**
   * 处理错误
   */
  handleError(error) {
    this.emit('onError', error)
  }
  
  /**
   * 添加事件监听器
   */
  addEventListener(eventType, callback) {
    if (this.listeners[eventType]) {
      this.listeners[eventType].push(callback)
    }
  }
  
  /**
   * 移除事件监听器
   */
  removeEventListener(eventType, callback) {
    if (this.listeners[eventType]) {
      const index = this.listeners[eventType].indexOf(callback)
      if (index > -1) {
        this.listeners[eventType].splice(index, 1)
      }
    }
  }
  
  /**
   * 触发事件
   */
  emit(eventType, data) {
    if (this.listeners[eventType]) {
      this.listeners[eventType].forEach(callback => {
        try {
          callback(data)
        } catch (error) {
          console.error('WebSocket事件监听器执行错误:', error)
        }
      })
    }
  }
  
  /**
   * 获取连接状态
   */
  getConnectionState() {
    return {
      isConnected: this.isConnected,
      userId: this.userId,
      reconnectAttempts: this.reconnectAttempts,
      readyState: this.ws ? this.ws.readyState : WebSocket.CLOSED
    }
  }
}

// 创建全局实例
const webSocketClient = new WebSocketClient()

export default webSocketClient
